/*******************************************************************
* ++
* Author        :	ThienTN
* Description   :	Employee.cpp in project HRManage
* 
* Mod. History  :	26/07/2012 - ThienTN
*
* --
*******************************************************************/

#include "Employee.h"

/*
 * Init  value for Employee
 */
CEmployee::CEmployee(void)
{
	m_wszID = "";
	m_wszName = "";
	m_birthDay.m_nDate = 1;
	m_birthDay.m_nMonth = 2;
	m_birthDay.m_nYear = 3;
	m_wszGradSchool = "";
	m_nGradType = 1;
	m_nEmpType = 0;
}


CEmployee::~CEmployee(void)
{
}

/*
 * Input value for Employee
 * param pEmployee a pointer of Employee
 */
void CEmployee::inputEmployee( CEmployee *pEmployee )
{
	//Input ID
	cout << "\tInput ID: ";
	cin >> pEmployee->m_wszID;

	// Input employee's name
	cout << "\tInput name: ";
	cin >> pEmployee->m_wszName;

	// Input employee's birthday
	cout << "\tInput Birthday(dd mm yy): ";
	cin >> (pEmployee->m_birthDay.m_nDate);
	cin >> (pEmployee->m_birthDay.m_nMonth);
	cin >> (pEmployee->m_birthDay.m_nYear);
	while (!CheckBirthday(pEmployee))
	{
		cout << "\tInput Birthday(dd mm yy): ";
		cin >> (pEmployee->m_birthDay.m_nDate);
		cin >> (pEmployee->m_birthDay.m_nMonth);
		cin >> (pEmployee->m_birthDay.m_nYear);
	}

	// Input employee's grad school
	cout << "\tInput Graduated School: ";
	cin >> pEmployee->m_wszGradSchool;

	// Input employee's gradType
	cout << "\tInput Graduate Type: " <<endl;
	cout << "\t\tBAD       :  1" <<endl;
	cout << "\t\tWEAK      :  2" <<endl;
	cout << "\t\tMEDIUM    :  3" <<endl;
	cout << "\t\tPRETTY    :  4" <<endl;
	cout << "\t\tGOOD      :  5" <<endl;
	cout << "\t\tEXCELLENT :  6" <<endl;
	cin >> pEmployee->m_nGradType;
	// Re-input grad type if input invalid
	while (pEmployee->m_nGradType > 6 || pEmployee->m_nGradType < 1)
	{
		cout << "\tInput Graduate Type: " <<endl;
		cout << "\t\tBAD       :  1" <<endl;
		cout << "\t\tWEAK      :  2" <<endl;
		cout << "\t\tMEDIUM    :  3" <<endl;
		cout << "\t\tPRETTY    :  4" <<endl;
		cout << "\t\tGOOD      :  5" <<endl;
		cout << "\t\tEXCELLENT :  6" <<endl;
		cin >> pEmployee->m_nGradType;
	}

}

/*
 * Search all manager 
 * param pEmployee a pointer of employee
 * param pList a pointer of list employee
 */
void CEmployee::searchEmployee( List *pList, CEmployee *pEmployee )
{
	Node *pNode;
	pNode = pList->pHead;
	while (pNode != NULL)
	{
		//Compare 2 employee name
		if (pNode->info->m_nEmpType == 2)
		{
			cout << "Employee ID				: " << pNode->info->m_wszID <<endl;
			cout << "Employee Name				: " << pNode->info->m_wszName <<endl;
			cout << "Employee Birthday			: " << pNode->info->m_birthDay.m_nDate << "-" << pNode->info->m_birthDay.m_nMonth << "-" << pNode->info->m_birthDay.m_nYear <<endl;
			cout << "Employee Graduated School  : " << pNode->info->m_wszGradSchool <<endl;
			cout << "Employee Graduated Type	: " << GetGradType(pNode->info->m_nGradType) <<endl;
			cout << "Employee Employee Type		: " << GetEmpType(pNode->info->m_nEmpType) <<endl;
			cout << endl;
		}
		pNode = pNode->pNext; // move to next Node
	}
}

/*
 * Clear list employee 
 * param pList a pointer of list employee
 */
void CEmployee::RemoveEmployee( List *pList )
{
	Node *pNode;
	while(pList->pHead != NULL)
	{
		pNode = pList->pHead;
		pList->pHead = pNode->pNext;
		delete pNode; // delete Node
	}
}

/*
 * Sort list employee by Name
 * param pList a pointer of list employee
 */
void CEmployee::sortName( List *pList )
{
	Node *pNode, *pNodeX;
	List l1, l2; 
	if (pList->pHead == pList->pTail) return;
	// create 2 list to contain node
	CreateList(&l1);
	CreateList(&l2);
	pNodeX = pList->pHead;
	pList->pHead = pNodeX->pNext;

	// if list is not empty
	while (pList->pHead != NULL)
	{
		pNode=pList->pHead;
		pList->pHead = pNode->pNext;
		pNode->pNext = NULL;
		// compare name of node with first node
		if (pNode->info->m_wszName.compare(pNodeX->info->m_wszName) < 0)
		{
			AddHead(&l1,pNode); // add to first if node's name < first node's name
		}
		else
			AddHead(&l2,pNode); // add to first if node's name > first node's name
	}

	// recursive function
	sortName(&l1);
	sortName(&l2);
	// combine 2 list
	if (l1.pHead != NULL)
	{
		pList->pHead = l1.pHead;
		l1.pTail->pNext = pNodeX;
	}

	else
		pList->pHead = pNodeX;
	pNodeX->pNext = l2.pHead;
	if (l2.pHead != NULL)
		pList->pTail = l2.pTail;
	else
		pList->pTail = pNodeX;
}

/*
 * Sort list employee by Employee Type
 * param pList a pointer of list employee
 */
 void CEmployee::sortEmpType( List *pList )
{
	Node *pNode, *pNodeX;
	List l1, l2; 
	if (pList->pHead == pList->pTail) return;
	// create 2 list to contain node
	CreateList(&l1);
	CreateList(&l2);
	pNodeX = pList->pHead;
	pList->pHead = pNodeX->pNext;

	// if list is not empty
	while (pList->pHead != NULL)
	{
		pNode=pList->pHead;
		pList->pHead = pNode->pNext;
		pNode->pNext = NULL;
		// compare name of node with first node
		if (pNode->info->m_nEmpType < pNodeX->info->m_nEmpType)
		{
			AddHead(&l1,pNode); // add to first if node's name < first node's name
		}
		else
			AddHead(&l2,pNode); // add to first if node's name > first node's name
	}

	// recursive function
	sortName(&l1);
	sortName(&l2);
	// combine 2 list
	if (l1.pHead != NULL)
	{
		pList->pHead = l1.pHead;
		l1.pTail->pNext = pNodeX;
	}

	else
		pList->pHead = pNodeX;
	pNodeX->pNext = l2.pHead;
	if (l2.pHead != NULL)
		pList->pTail = l2.pTail;
	else
		pList->pTail = pNodeX;
}

/*
 * Check validate of birthday
 * param pList a pointer of list employee
 */
bool CheckBirthday( CEmployee *pEmployee )
{
	bool temp = true;
	// Check year valid
	if (pEmployee->m_birthDay.m_nYear < 0 || pEmployee->m_birthDay.m_nYear > 2012)
	{
		cout << "Year is not available!" <<endl;
		return false;
	}
	else
	{
		// Check month valid
		if (pEmployee->m_birthDay.m_nMonth < 1 || pEmployee->m_birthDay.m_nMonth >12)
		{
			cout << "Month is not available!" << endl;
			return false;
		} 
		else
		{
			if (pEmployee->m_birthDay.m_nMonth == 1 || pEmployee->m_birthDay.m_nMonth == 3 || pEmployee->m_birthDay.m_nMonth == 5 || pEmployee->m_birthDay.m_nMonth == 7 || pEmployee->m_birthDay.m_nMonth == 8 || pEmployee->m_birthDay.m_nMonth == 10 || pEmployee->m_birthDay.m_nMonth == 12)
			{
				// Check month has 31 days.
				if (pEmployee->m_birthDay.m_nDate < 1 || pEmployee->m_birthDay.m_nDate > 31)
				{
					cout << "Day is not available!" <<endl;
					return false;
				}
			} 
			else
			{
				if (pEmployee->m_birthDay.m_nMonth == 4 || pEmployee->m_birthDay.m_nMonth == 6 || pEmployee->m_birthDay.m_nMonth == 9 || pEmployee->m_birthDay.m_nMonth == 11)
				{
					// Check month has 30 days.
					if (pEmployee->m_birthDay.m_nDate < 1 || pEmployee->m_birthDay.m_nDate > 30)
					{
						cout << "Day is not available!" << endl;
						return false;
					}
				} 
				else
				{
					if (pEmployee->m_birthDay.m_nMonth == 2)
					{
						if ((pEmployee->m_birthDay.m_nDate % 4 == 0 && pEmployee->m_birthDay.m_nDate % 100 != 0) || pEmployee->m_birthDay.m_nDate % 400 == 0)
						{
							// Check month has 29 days (Leap year).
							if (pEmployee->m_birthDay.m_nDate < 1 || pEmployee->m_birthDay.m_nDate > 29)
							{
								cout << "Day is not available!" << endl;
								return false;
							}
						} 
						else
						{
							// Check month has 28 days (Leap year).
							if (pEmployee->m_birthDay.m_nDate < 1 || pEmployee->m_birthDay.m_nDate > 28)
							{
								cout << "Day is not available!" << endl;
								return false;
							}
						}
					}
				}
			}
		}
	}
	return true;
}
